﻿using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
using UnityEngine.UIElements;

public class Monster : MonoBehaviour
{
    public static Action OnEndReached;  //定义了一个公有的静态事件
    [SerializeField] private float getMoney = 0f; //该怪物掉落功德值
    [SerializeField] private float moveSpeed = 3f;  //序列化的私有属性moveSpeed
    //[SerializeField] private Waypoint Waypoint;
    public Waypoint Waypoint { get; set; }
    public float GetMoney { get; set; }

    public Vector3 CurrentPointPosition => Waypoint.GetWaypointPosition(_currentWaypointIndex); //公有属性 CurrentPointPosition，返回对应index标记点的世界坐标

    private int _currentWaypointIndex; //私有变量类型为int，（索引）
    private MonsterHealth _monsterHealth;
    public float CurrentHealth { get; set; }

    private void Start()
    {
        GetMoney = getMoney;
        _currentWaypointIndex = 0;
        _monsterHealth = GetComponent<MonsterHealth>();
    }

    private void Update()
    {
        Move();  //运动方法
        if (CurrentPointPositionReached())
        {
            UpdateCurrentPointIndex();  //索引+1，直到索引为数组长度-1（具体在 UpdateCurrentPointIndex()方法中）
        }
    }
    private void Move()  //从初始的对象位置，移动到对应索引标记点的位置
    {
        transform.position = Vector3.MoveTowards(transform.position, CurrentPointPosition, moveSpeed * Time.deltaTime);
    }

    /*在这段代码中，使用了 Vector3.MoveTowards 方法来实现平滑的移动效果。该方法接受三个参数：起始位置、目标位置和移动速度。在这里，
     * 起始位置是当前对象的位置 transform.position，目标位置是 CurrentPointPosition（根据索引标记点计算得到的位置），移动速度通过 moveSpeed 变量控制。
     * 通过调用 Vector3.MoveTowards 方法，并将返回的位置赋值给 transform.position，可以使对象在每一帧上根据指定的移动速度向目标位置移动。
     * Time.deltaTime 用于平滑计算移动距离，使得移动速度与帧率无关。总的来说，这段代码的作用是实现对象的平滑移动，从当前位置向索引标记点的位置移动，
     * 移动速度由 moveSpeed 变量控制。*/
    public void DealDamage(float attackDamage)
    {
        CurrentHealth = _monsterHealth.CurrentHealth;
        CurrentHealth -= attackDamage;
        _monsterHealth.CurrentHealth = CurrentHealth;
    }

    private bool CurrentPointPositionReached()  //一个返回bool类型的方法，判断游戏对象是否到达对应目标点
    {
        float distanceToNextPointPosition = (transform.position - CurrentPointPosition).magnitude;
        if (distanceToNextPointPosition < 0.1f)
        {
            return true;
        }
        return false;
    }

    private void UpdateCurrentPointIndex()  //未到最后一个标记点时，索引+1，到达最后一个时，对象返回池中并设置为未激活状态（详细见ObjectPooler中的ReturnToPool(GameObject instance)方法）
    {
        int lastWaypointIndex = Waypoint.Points.Length - 1;
        if (_currentWaypointIndex < lastWaypointIndex)
        {
            _currentWaypointIndex++;
        }
        else
        {
            //if (OnEndReached != null)  //敌人到最后一个标记点，如果OnEndReached事件有订阅者，则激活该事件，触发所有方法
            //{
            //    OnEndReached.Invoke();
           // }
            //等同于OnEndReached?.Invoke();
            EndPointReached();
        }
    }

    private void EndPointReached()
    {
        OnEndReached?.Invoke();
        _monsterHealth.ResetHealth();
        ObjectPooler.ReturnToPool(gameObject);
    }
    //gameObject 是 MonoBehaviour 类的一个属性，它是 Unity 引擎提供的一个成员变量。每个 MonoBehaviour 类都具有这个属性，它表示当前脚本所附加的游戏对象。

    public void ResetMonster()
    {
        _currentWaypointIndex = 0;
    }

}
